package io.r2mo.test.common;

import io.r2mo.spring.junit5.AppBaseTestSupport;
import io.r2mo.test.common.domain.OrderEntity;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.stereotype.Component;
import org.springframework.test.context.TestPropertySource;
import org.springframework.transaction.annotation.Transactional;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Set;

/**
 * @author lang : 2025-09-06
 */
@SpringBootTest(classes = TestCommonApplication.class)
@Transactional
@TestPropertySource("classpath:env-test.properties")
@Component
@Slf4j
public class IoOperationActTestCase extends AppBaseTestSupport<OrderEntity> {

    @BeforeEach
    public void before() {
        this.runOnce(() -> {
            // 确认文件操作
            final String testPath = "HFS/file/";
            final String testCp = "HFS/target-cp/";
            this.fs().mkdir(Set.of(
                testPath, testCp
            ));
            // 删除目录
            final String testRmFile = "HFS/file/file-rm.txt";
            this.fs().write(testRmFile, "R2MO 文件删除测试", false);
            final String testRmFiles = "HFS/files/content/file-rm.txt";
            this.fs().write(testRmFiles, "R2MO 文件创建测试（无目录）", false);
        });
    }

    @Test
    public void testAppendFile() {
        final String testFile = "HFS/files/content/file-rm.txt";
        this.fs().write(testFile, "\nR2MO 文件创建测试（无目录）- 追加内容", true);
        final String contentIn = this.fs().inString(testFile);
        log.info("[ R2MO ] (4) testAppendFile / 读取文件内容：\n{} ", contentIn);
        Assertions.assertTrue(contentIn.contains("追加内容"));
        this.fs().rm(testFile);
        log.info("[ R2MO ] (4) testAppendFile / 文件追加成功：{} ", testFile);
        // 删除父目录
        this.fs().rm("HFS/files");
    }

    @Test
    public void testMoveDirectory() {
        final String source = "HFS/source";
        // 目录不存在，创建此目录，拷贝目标：HFS/target-cp-v1
        final String target1 = "HFS/target-cp-from";
        final String target2 = "HFS/target-cp-to";
        this.fs().cp(source, target1);   // 最终拷贝内容到 target-cp-v1 之下
        final boolean isSame = this.fs().isSame(source, target1);
        Assertions.assertTrue(isSame);

        // 转移
        this.fs().mv(target1, target2);
        Assertions.assertFalse(this.fs().isExist(target1));
        final boolean isSame2 = this.fs().isSame(source, target2);
        Assertions.assertTrue(isSame2);
        log.info("[ R2MO ] (5) testMoveDirectory / 目录拷贝测试完成！");
        this.fs().rm(Set.of(
            target2
        ));
    }

    @Test
    public void testCopyDirectory() {
        final String source = "HFS/source";
        // 目录不存在，创建此目录，拷贝目标：HFS/target-cp-v1
        final String target1 = "HFS/target-cp-v1";
        // 目录已存在，不创建目录，直接拷贝到之下： HFS/target-cp/source
        final String target2 = "HFS/target-cp";
        this.fs().cp(source, target1);   // 最终拷贝内容到 target-cp-v1 之下
        this.fs().cp(source, target2);  // 最终拷贝内容到 target-cp/source 之下
        log.info("[ R2MO ] (0) testCopyDirectory / 目录拷贝测试完成！");
        final boolean isSame = this.fs().isSame(target1, target2 + "/source");
        Assertions.assertTrue(isSame);
        // 检查原始目录应该存在
        Assertions.assertTrue(this.fs().isExist(source));
        this.fs().rm(Set.of(
            target1,
            target2
        ));
    }

    @Test
    public void testCreateDirectory() {
        final String testPath = "HFS/directory/dir-created";
        final boolean created = this.fs().mkdir(testPath);
        final Path directory = Paths.get(testPath);
        Assertions.assertTrue(created);
        Assertions.assertTrue(Files.exists(directory));
        Assertions.assertTrue(Files.isDirectory(directory));
        this.fs().rm(directory.toString());
        log.info("[ R2MO ] (1) testCreateDirectory / 目录创建成功：{}", testPath);
    }

    @Test
    public void testCreateFile() {

        final String content = "R2MO 文件创建测试";
        final String testFile = "HFS/file/file-created.txt";
        final boolean created = this.fs().write(testFile, content, false);
        Assertions.assertTrue(created);

        final String contentIn = this.fs().inString(testFile);
        log.info("[ R2MO ] (2) testCreateFile / 读取文件内容：\n{} ", contentIn);
        Assertions.assertEquals(content, contentIn);

        final Path file = Paths.get(testFile);
        Assertions.assertTrue(Files.exists(file));
        Assertions.assertTrue(Files.isRegularFile(file));
        this.fs().rm(file.toString());
        log.info("[ R2MO ] (2) testCreateFile / 文件创建成功：{} ", testFile);
    }

    @Test
    public void testDeleteFile() {
        final String testRmFile = "HFS/file/file-rm.txt";
        final boolean deleted = this.fs().rm(testRmFile);
        Assertions.assertTrue(deleted);
        final Path file = Paths.get(testRmFile);
        Assertions.assertFalse(Files.exists(file));
        log.info("[ R2MO ] (3) testDeleteFile / 文件删除成功：{} ", testRmFile);
    }
}
